import React, { createContext, useContext, useEffect, useState } from 'react';
import { useWallet } from './WalletContext';
import axios from 'axios';
import toast from 'react-hot-toast';

const AuthContext = createContext();

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

const API_BASE_URL = process.env.REACT_APP_API_URL || 'http://localhost:3001/api';

export const AuthProvider = ({ children }) => {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [user, setUser] = useState(null);
  const [token, setToken] = useState(localStorage.getItem('token'));
  const [isLoading, setIsLoading] = useState(true);

  const { account, signMessage } = useWallet();

  useEffect(() => {
    if (token) {
      validateToken();
    } else {
      setIsLoading(false);
    }
  }, [token]);

  useEffect(() => {
    if (account && !isAuthenticated) {
      // Auto-login if wallet is connected and we have a stored token
      if (token) {
        validateToken();
      }
    } else if (!account && isAuthenticated) {
      // Logout if wallet is disconnected
      logout();
    }
  }, [account]);

  const validateToken = async () => {
    try {
      const response = await axios.get(`${API_BASE_URL}/users/profile`, {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      setUser(response.data);
      setIsAuthenticated(true);
    } catch (error) {
      console.error('Token validation failed:', error);
      logout();
    } finally {
      setIsLoading(false);
    }
  };

  const login = async (password) => {
    if (!account) {
      toast.error('Please connect your wallet first');
      return false;
    }

    try {
      const response = await axios.post(
        `${API_BASE_URL}/auth/login`,
        {
          walletAddress: account,
          password,
        }
      );

      const { token: newToken, user: userData } = response.data;

      localStorage.setItem('token', newToken);
      setToken(newToken);
      setUser(userData);
      setIsAuthenticated(true);

      toast.success('Login successful');
      return true;
    } catch (error) {
      console.error('Login error:', error);
      const message = error.response?.data?.error || 'Login failed';
      toast.error(message);
      return false;
    }
  };

  const register = async (password, referralCode = '') => {
    if (!account) {
      toast.error('Please connect your wallet first');
      return false;
    }

    try {
      const response = await axios.post(
        `${API_BASE_URL}/auth/register`,
        {
          walletAddress: account,
          password,
          referralCode,
        }
      );

      const { token: newToken, referralCode: newReferralCode } = response.data;

      localStorage.setItem('token', newToken);
      setToken(newToken);
      setIsAuthenticated(true);

      toast.success('Registration successful');
      toast.success(`Your referral code: ${newReferralCode}`);
      return true;
    } catch (error) {
      console.error('Registration error:', error);
      const message = error.response?.data?.error || 'Registration failed';
      toast.error(message);
      return false;
    }
  };

  const logout = () => {
    localStorage.removeItem('token');
    setToken(null);
    setUser(null);
    setIsAuthenticated(false);
    toast.success('Logged out successfully');
  };

  const updateProfile = async (data) => {
    try {
      const response = await axios.put(
        `${API_BASE_URL}/users/profile`,
        data,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        }
      );

      setUser(prev => ({ ...prev, ...response.data }));
      toast.success('Profile updated successfully');
      return true;
    } catch (error) {
      console.error('Profile update error:', error);
      const message = error.response?.data?.error || 'Profile update failed';
      toast.error(message);
      return false;
    }
  };

  const apiCall = async (method, endpoint, data = null) => {
    try {
      const config = {
        method,
        url: `${API_BASE_URL}${endpoint}`,
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      };

      if (data) {
        config.data = data;
      }

      const response = await axios(config);
      return response.data;
    } catch (error) {
      console.error('API call error:', error);
      const message = error.response?.data?.error || 'Request failed';
      toast.error(message);
      throw error;
    }
  };

  const value = {
    isAuthenticated,
    user,
    token,
    isLoading,
    login,
    register,
    logout,
    updateProfile,
    apiCall,
  };

  return (
    <AuthContext.Provider value={value}>
      {children}
    </AuthContext.Provider>
  );
};